#pragma once
#include <memory>
#include "field.hpp"
#include <functional>
namespace qiangsir
{
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;
        virtual ~BaseMessage() {};
        virtual void setType(MType type)
        {
            _mytype = type;
        }
        virtual MType mtype() { return _mytype; }
        virtual void setId(const std::string &Id)
        {
            _rid = Id;
        }
        virtual std::string id() { return _rid; }
        virtual std::string serialize() = 0;
        virtual bool deSerialize(const std::string &message) = 0;
        virtual bool check() = 0;

    private:
        MType _mytype;
        std::string _rid;
    };

    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;
        virtual size_t readableSize() = 0;
        virtual int32_t peekInt32() = 0;
        virtual void retrieveInt32() = 0;
        virtual int32_t readInt32() = 0;
        virtual std::string retrieveAsString(size_t len) = 0;
    };

    class BaseProtocal
    {
    public:
        using ptr = std::shared_ptr<BaseProtocal>;
        virtual bool canProcessed(const BaseBuffer::ptr &buf) = 0;
        virtual bool onMessage(const BaseBuffer::ptr &buf, BaseMessage::ptr &message) = 0;
        virtual std::string serialize(const BaseMessage::ptr &message) = 0;
    };

    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        virtual void send(const BaseMessage::ptr &msg) = 0;
        virtual void shutDown() = 0;
        virtual bool connected() = 0;
    };

    using ConnectionCallBack = std::function<void(const BaseConnection::ptr &)>;
    using CloseCallBack = std::function<void(const BaseConnection::ptr &)>;
    using MessageCallBack = std::function<void(const BaseConnection::ptr &, BaseMessage::ptr &)>;

    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;
        virtual void setConnectionCallBack(const ConnectionCallBack& cb) {_cb_connection = cb;}
        virtual void setCloseCallBack(const CloseCallBack& cb) {_cb_close = cb;}
        virtual void setMessageCallBack(const MessageCallBack& cb) {_cb_message = cb;}
        virtual void start() = 0;
    protected:
        ConnectionCallBack _cb_connection;
        CloseCallBack _cb_close;
        MessageCallBack _cb_message;
    };


    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;
        virtual void setConnectionCallBack(const ConnectionCallBack& cb) {_cb_connection = cb;}
        virtual void setCloseCallBack(const CloseCallBack& cb) {_cb_close = cb;}
        virtual void setMessageCallBack(const MessageCallBack& cb) {_cb_message = cb;}
        virtual void connect() = 0;
        virtual void shutDown() = 0;
        virtual BaseConnection::ptr connection() = 0;
        virtual bool send(const BaseMessage::ptr&) = 0;
        virtual bool connected() = 0;
    protected:
        ConnectionCallBack _cb_connection;
        CloseCallBack _cb_close;
        MessageCallBack _cb_message;
    };
};